package com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.frames;

import java.io.IOException;
import java.nio.channels.ReadableByteChannel;

import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.core.Frame;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.core.IoArgs;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.core.SendPacket;

public class SendEntityFrame extends AbsSendPacketFrame {
    private final ReadableByteChannel channel;
    private final long unConsumeEntityLength; // 未消费的长度

    SendEntityFrame(short identifier,
                    long entityLength,
                    ReadableByteChannel channel,
                    SendPacket packet) {
        super((int) Math.min(entityLength, Frame.MAX_CAPACITY), // 不能超过每一帧的最大长度
                Frame.TYPE_PACKET_ENTITY,
                Frame.FLAG_NONE,
                identifier,
                packet);
        // 假设要发送的数据：1234567890
        // 第一帧：1234；第二帧：5678，第三帧：90
        // 第一次长度10，第一帧发送4个字节，剩余6个字节；第二帧发送4个字节，剩余2个字节；第三次发送2个字节
        this.unConsumeEntityLength = entityLength - bodyRemaining; // 总长度 - 当前可以消费的body长度
        this.channel = channel;
    }

    @Override
    protected int consumeBody(IoArgs args) throws IOException {
        if (packet == null) {
            // 已终止当前帧，则填充假数据
            return args.fillEmpty(bodyRemaining);
        }
        return args.readFrom(channel);
    }

    @Override
    public Frame buildNextFrame() {
        if (unConsumeEntityLength == 0) {
            return null;
        }
        // 将未消费的长度用于构建下一帧
        return new SendEntityFrame(getBodyIdentifier(), unConsumeEntityLength, channel, packet);
    }
}
